package QianFeng08.GuavaDemo;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.collect.*;
import com.google.common.collect.Sets.SetView;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Guava:
 * Guava是一种基于开源的Java库，其中包含谷歌正在由他们很多项目使用的很多核心库。
 *
 * guava对集合的支持：
 * 1、只读设置
 * 2、函数式编程:过滤器
 * 3、函数式编程:转换
 * 4、组合式函数编程
 * 5、加入约束:非空、长度验证
 * 6、集合操作:交集、差集、并集
 * 7、Multiset: 无序可重复
 * 8、Multimap key可以重复
 * 9、BiMap: 双向Map(bidirectional Map)键与值不能重复
 * 10、双键的Map -->Table -->-rowKey+columnKye +value
 **/
public class GuavaDemo {
    public static void main(String[] args) {
        GuavaDemo guavaDemo = new GuavaDemo();
        //guavaDemo.testGuava1();
        //guavaDemo.testGuava2();
        //guavaDemo.testGuava3();
        //guavaDemo.testGuava4();
        //guavaDemo.testGuava6();
        //guavaDemo.testGuava7();
        //guavaDemo.testGuava8();
        //guavaDemo.testGuava9();
        guavaDemo.testGuava10();

    }

    //只读设置
    public void testGuava1() {
        //将IList变为只读，不能添加数据
        ImmutableList<String> iList = ImmutableList.of("jack", "tom", "lily", "bin");
    }

    //过滤器
    public void testGuava2() {
        List<String> list = Lists.newArrayList("java", "php", "python", "javascript");
        Collection<String> result = Collections2.filter(list, (e) -> {
            assert e != null;
            return e.startsWith("j");//将j打头的字符串输出出来
        });
        result.forEach(System.out::println);
    }

    //转换
    public void testGuava3() {
        Set<Long> timeSet = Sets.newHashSet(20201209L, 20210423L, 20220927L);
        Collection<String> timeCollection = Collections2.transform(timeSet, e -> {
            return new SimpleDateFormat("yyyy-MM-dd").format(e);
        });
        timeCollection.forEach(System.out::println);
    }

    //组合式函数
    public void testGuava4() {
        List<String> list = Lists.newArrayList("jack", "tom", "lily", "big12345");
        Function<String, String> f1 = new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.length() > 4 ? s.substring(0, 4) : s;//截取4个字符
            }
        };
        Function<String, String> f2 = new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.toUpperCase();//转换成大写
            }
        };
        Function<String, String> f = Functions.compose(f1, f2);
        Collection<String> collection = Collections2.transform(list, f);
        collection.forEach(System.out::println);

    }

    //加入约束：非空、长度验证
    public void testGuava5() {
        Set<String> set = Sets.newHashSet();
        //14可用
        /*Constraint<String> constraints = new Constraint<>(){
            @Override
            public String checkElement(String element) {

            }
        }*/
        //为空，参数异常会抛出异常
        //Preconditions.checkArgument(Expression);
        //Preconditions.checkNotNull(reference);
    }

    //集合操作:交集、差集、并集
    public void testGuava6() {
        Set<Integer> set1 = Sets.newHashSet(1, 2, 3);
        Set<Integer> set2 = Sets.newHashSet(3, 4, 5);
        //交集
        SetView<Integer> v1 = Sets.intersection(set1, set2);
        v1.forEach(System.out::println);
        //差集
        SetView<Integer> v2 = Sets.difference(set1, set2);
        v2.forEach(System.out::println);
        //并集
        SetView<Integer> v3 = Sets.union(set1, set2);
        v3.forEach(System.out::println);
    }

    //Multiset: 无序可重复
    public void testGuava7() {
        String s = "good good study day day up";
        String[] ss = s.split(" ");
        HashMultiset<String> set = HashMultiset.create();
        for (String str : ss) {
            set.add(str);
        }
        //set.addAll(Arrays.asList(ss));  简化
        Set<String> set2 = set.elementSet();
        for (String str : set2) {
            System.out.println(str + ":" + set.count(str));
        }

    }

    //Multimap key可以重复
    public void testGuava8() {
        Map<String, String> map = new HashMap<>();
        map.put("java从入门到放弃", "bin");
        map.put("python从入门到入土", "bin");
        map.put("PHP从入门到精通", "jack");
        map.put("笑看人生", "sun");

        Multimap<String, String> mmap = ArrayListMultimap.create();
        Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = iter.next();
            mmap.put(entry.getValue(), entry.getKey());
        }
        Set<String> keysSet = mmap.keySet();
        for (String key : keysSet) {
            Collection<String> values = mmap.get(key);
            System.out.println(key + "->" + values);
        }

    }

    //BiMap: 双向Map(bidirectional Map)键与值不能重复
    public void testGuava9() {
        BiMap<String,String > biMap = HashBiMap.create();
        biMap.put("finally_test", "15475784446");
        biMap.put("bin_test", "18883838438");
        String name = biMap.inverse().get("15475784446");//inverse() key与value反转
        System.out.println(name);
    }

    //双键的Map -->Table -->-rowKey+columnKye +value
    public void testGuava10() {
        Table<String, String, Integer> table = HashBasedTable.create();
        table.put("jack", "java", 80);
        table.put("tom", "ui", 70);
        table.put("vince", "php", 59);
        table.put("sun", "java", 95);

        Set<Table.Cell<String, String, Integer>> cells = table.cellSet();
        for (Table.Cell c : cells) {
            System.out.println(c.getRowKey() + "-" + c.getColumnKey() + "-" + c.getValue());
        }
    }
}


